package com.distributed.common.message;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.distributed.common.Constant;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

public class BaseMessage {
	
	protected String version = null;
	private int MESSAGEId = Constant.BASE_MESSAGE;
	protected Map<String, String> argv = new HashMap<String, String>();

	public BaseMessage() {
		long timestamp = System.currentTimeMillis();
		String ip = null;
		try {
			InetAddress address = InetAddress.getLocalHost();
			ip = address.getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		int port = Constant.PORT;
		version = ip + ":" + String.valueOf(port) + ":"
				+ String.valueOf(timestamp);
	}

	public int getId() {
		return MESSAGEId;
	}

	public void setId(int cid) {
		MESSAGEId = cid;
	}

	public static String getName() {
		return Constant.BASE_MESSAGE_NAME;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String getArgvValue(String name) {
		return argv.get(name);
	}

	public void setArgvValue(String name, String value) {
		argv.put(name, value);
	}

	public static BaseMessage getFromString(String message) {
		JSONObject jsonobject = JSONObject.fromObject(message);
		if (jsonobject == null) {
			return null;
		}
		return getFromJSON(jsonobject);
	}

	protected static BaseMessage getFromJSON(JSONObject jsonobj) {
		BaseMessage baseMessage = new BaseMessage();
		return getFromJSON(jsonobj, baseMessage);
	}

	protected static BaseMessage getFromJSON(JSONObject jsonobj,
			BaseMessage baseMessage) {
		if (jsonobj == null || baseMessage == null) {
			return null;
		}

		if (jsonobj.containsKey(Constant.MESSAGE_VERSION) == false
				|| jsonobj.containsKey(Constant.MESSAGE_ID) == false) {
			return null;
		}
		baseMessage.setVersion(jsonobj.getString(Constant.MESSAGE_VERSION));
		baseMessage.setId(jsonobj.getInt(Constant.MESSAGE_ID));
		try {
			if (jsonobj.containsKey(Constant.MESSAGE_ARGV) == false) {
				return baseMessage;
			}
			JSONArray jsonarray = jsonobj.getJSONArray(Constant.MESSAGE_ARGV);
			if (jsonarray.isEmpty()) {
				return baseMessage;
			}
			for (int i = 0; i < jsonarray.size(); i++) {
				JSONObject tmp = jsonarray.getJSONObject(i);
				if (tmp.isEmpty()) {
					continue;
				}
				Iterator<?> it = tmp.keys();
				while (it.hasNext()) {
					String key = (String) it.next();
					if (key == null) {
						continue;
					}
					String value = tmp.getString(key);
					baseMessage.setArgvValue(key, value);
				}
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return baseMessage;
	}

	protected JSONObject toJSON() {
		JSONObject jsonobj = new JSONObject();
		jsonobj.put(Constant.MESSAGE_VERSION, getVersion());
		jsonobj.put(Constant.MESSAGE_ID, getId());
		JSONArray jsonarray = new JSONArray();
		Iterator<Entry<String, String>> it = argv.entrySet().iterator();
		while (it.hasNext()) {
			Entry<String, String> entry = it.next();
			String key = entry.getKey();
			String value = entry.getValue();
			JSONObject tmp = new JSONObject();
			tmp.put(key, value);
			jsonarray.add(tmp);
		}
		if (jsonarray.isEmpty() == false) {
			jsonobj.put(Constant.MESSAGE_ARGV, jsonarray);
		}
		return jsonobj;
	}
	
	public String toString() {
		return toJSON().toString();
	}
}
